// Huben.hpp
#ifndef HUBEN_HPP
#define HUBEN_HPP

#include <QObject>
#include <QVariant>
#include <QMap>
#include <functional>
#include <QMutex>
#include <QDebug>
#include <QSet>
#include "store/type/ActionWrapper.hpp"
#include "plugin/IPlugin.hpp"

/**

    auto handler = [](const QVariant &value) {
        qDebug() << "状态改变，新的值:" << value;
    };

    // 注册处理函数
    HandlerId id = Huben::instance().registerStateChangedHandler(ActionWrapper::StateKey::SomeKey, handler);

    // 触发状态改变
    Huben::instance().setState(ActionWrapper::StateKey::SomeKey, QVariant(42));

    // 注销处理函数
    Huben::instance().unregisterStateChangedHandler(ActionWrapper::StateKey::SomeKey, id);

    #include <QPointer>
    // 再次触发状态改变，处理函数不会被调用
    Huben::instance().setState(ActionWrapper::StateKey::SomeKey, QVariant(100));

        QPointer<GanttChartModel> weakPtr(this);

        // 在 lambda 中捕获 weakPtr
        Huben::instance().registerStateChangedHandler(ActionWrapper::StateKey::Synthetic, [weakPtr](const QVariant &value) {
            if (!weakPtr) return;

            if (value.canConvert<Synthetic>()) {
                Synthetic synthetic = value.value<Synthetic>();
                if (!synthetic.startTime.isValid() || !synthetic.endTime.isValid()) {
                    qWarning() << "Synthetic contains invalid QDateTime objects";
                    return;
                }
                weakPtr->setMinTime(synthetic.startTime);
                weakPtr->setMaxTime(synthetic.endTime);
                weakPtr->setDiagrams(synthetic.diagrams);
                // 其他逻辑
            } else {
                qWarning() << "Received QVariant cannot be converted to Synthetic";
            }
        });

        // 初始请求数据
        Huben::instance().dispatch(ActionWrapper::ActionType::InitModify, QVariant::fromValue(MetaMoldType::Rhythm));
    }


 */

// 定义 HandlerId 类型
using HandlerId = int;

// 定义状态管理类 Huben
class Huben : public QObject {
    Q_OBJECT

public:
    // 获取单例实例
    static Huben& instance() {
        static Huben instance;
        return instance;
    }

    // 禁用拷贝构造和赋值操作
    Huben(const Huben&) = delete;
    Huben& operator=(const Huben&) = delete;

    // 修改后的 setState 方法
    void setState(ActionWrapper::StateKey key, const QVariant &value) {
        QVariant oldValue;
        bool changed = false;

        {
            QMutexLocker locker(&mutex);
            oldValue = state.value(key);
            if (oldValue != value) {
                state[key] = value;
                changed = true;
            }
        }

        if (changed) {
            emit stateChanged(key, value);
        }
    }

    QVariant getState(ActionWrapper::StateKey key) const {
        QMutexLocker locker(&mutex);
        return state.value(key, QVariant());
    }

    // 搜索函数，用于获取状态
    template <typename T>
    T search(ActionWrapper::StateKey key) const {
        QMutexLocker locker(&mutex);
        if (state.contains(key)) {
            return state[key].value<T>();
        } else {
            qWarning() << "未找到状态键:" << static_cast<int>(key);
            return T();
        }
    }

    // 修改后的 updateState 方法
    void updateState(ActionWrapper::StateKey key, const QVariant &value) {
        bool shouldEmit = false;

        {
            QMutexLocker locker(&mutex);
            state[key] = value;
            if (inTransaction) {
                changedKeys.insert(key);
            } else {
                shouldEmit = true;
            }
        }

        if (shouldEmit) {
            emit stateChanged(key, value);
        }
    }

    // 提交 Mutation
    void commit(ActionWrapper::ActionType actionType, const QVariant &payload) {
        std::function<void(const QVariant&)> mutation;
        std::function<void(const QVariant&)> mutationCallback;
        ActionWrapper::StateKey stateKey;

        {
            QMutexLocker locker(&mutex);
            if (mutations.contains(actionType)) {
                mutation = mutations[actionType].first;
                mutationCallback = mutations[actionType].second;
                stateKey = actionTypeToStateKey[actionType];
            } else {
                qWarning() << "未找到动作类型的 Mutation:" << static_cast<int>(actionType);
                return;
            }
        }

        // 调用 Mutation 处理函数
        mutation(payload);

        // 调用 Mutation 回调函数
        if (mutationCallback) {
            mutationCallback(payload);
        }

        // 通知插件
        for (IPlugin *plugin : plugins) {
            plugin->onActionDispatched(actionType, payload);
        }
    }

    // 分发 Action
    void dispatch(ActionWrapper::ActionType actionType, const QVariant &payload) {
        std::function<void(const QVariant&)> action;
        std::function<void(const QVariant&)> actionCallback;

        {
            QMutexLocker locker(&mutex);
            if (actions.contains(actionType)) {
                action = actions[actionType].first;
                actionCallback = actions[actionType].second;
            } else {
                qWarning() << "未找到动作类型的 Action 处理函数:" << static_cast<int>(actionType);
                return;
            }
        }
        action(payload);

        // 调用 Action 回调函数
        if (actionCallback) {
            actionCallback(payload);
        }

        // 通知插件
        for (IPlugin *plugin : plugins) {
            plugin->onActionDispatched(actionType, payload);
        }
    }

    // 注册 Mutation 的处理函数和回调函数
    void registerMutation(ActionWrapper::ActionType actionType,
                          ActionWrapper::StateKey stateKey,
                          std::function<void(const QVariant&)> handler,
                          std::function<void(const QVariant&)> callback = nullptr) {
        QMutexLocker locker(&mutex);
        mutations[actionType] = qMakePair(handler, callback);
        actionTypeToStateKey[actionType] = stateKey;
    }

    // 注册 Action 的处理函数和回调函数
    void registerAction(ActionWrapper::ActionType actionType,
                        std::function<void(const QVariant&)> handler,
                        std::function<void(const QVariant&)> callback = nullptr) {
        QMutexLocker locker(&mutex);
        actions[actionType] = qMakePair(handler, callback);
    }

    // 注册插件
    void registerPlugin(IPlugin *plugin) {
        QMutexLocker locker(&mutex);
        plugins.append(plugin);
    }

    // 注册特定状态键的回调函数，返回 HandlerId
    HandlerId registerStateChangedHandler(ActionWrapper::StateKey key, std::function<void(const QVariant&)> handler) {
        QMutexLocker locker(&mutex);
        int handlerId = nextHandlerId++;
        stateChangedHandlers[key][handlerId] = handler;
        return handlerId;
    }

    // 注销特定状态键的回调函数，通过 HandlerId
    void unregisterStateChangedHandler(ActionWrapper::StateKey key, HandlerId handlerId) {
        QMutexLocker locker(&mutex);
        if (stateChangedHandlers.contains(key)) {
            stateChangedHandlers[key].remove(handlerId);
            // 如果该 key 下没有更多的处理函数，移除 key
            if (stateChangedHandlers[key].isEmpty()) {
                stateChangedHandlers.remove(key);
            }
        } else {
            qWarning() << "尝试注销未注册的 StateKey:" << static_cast<int>(key);
        }
    }

signals:
    void stateChanged(ActionWrapper::StateKey key, const QVariant &value);

private:
    // 私有构造函数
    explicit Huben(QObject *parent = nullptr) : QObject(parent), nextHandlerId(1) { // 初始化 HandlerId 从1开始
        connect(this, &Huben::stateChanged, this, &Huben::onStateChanged);
    }

    // 私有槽函数，调用注册的回调函数
    void onStateChanged(ActionWrapper::StateKey key, const QVariant &value) {
        // 暂时禁用信号，避免递归调用
        disconnect(this, &Huben::stateChanged, this, &Huben::onStateChanged);

        // 处理回调
        QList<std::function<void(const QVariant&)>> handlersCopy;
        {
            QMutexLocker locker(&mutex);
            if (stateChangedHandlers.contains(key)) {
                // 复制所有处理函数
                for (const auto &handlerPair : stateChangedHandlers[key]) {
                    handlersCopy.append(handlerPair);
                }
            }
        }

        for (const auto &handler : handlersCopy) {
            handler(value);
        }

        // 通知插件
        for (IPlugin *plugin : plugins) {
            plugin->onStateChanged(key, value);
        }

        // 重新连接信号
        connect(this, &Huben::stateChanged, this, &Huben::onStateChanged);
    }

    // 成员变量
    mutable QMutex mutex;
    QMap<ActionWrapper::StateKey, QVariant> state;
    QMap<ActionWrapper::ActionType, QPair<std::function<void(const QVariant&)>, std::function<void(const QVariant&)>>> mutations;
    QMap<ActionWrapper::ActionType, QPair<std::function<void(const QVariant&)>, std::function<void(const QVariant&)>>> actions;

    // 从 ActionType 到 StateKey 的映射
    QMap<ActionWrapper::ActionType, ActionWrapper::StateKey> actionTypeToStateKey;

    // 状态键到回调函数列表的映射，使用 HandlerId 进行管理
    QMap<ActionWrapper::StateKey, QMap<HandlerId, std::function<void(const QVariant&)>>> stateChangedHandlers;

    // 插件列表
    QList<IPlugin*> plugins;

    // 事务管理
    bool inTransaction = false;
    QMap<ActionWrapper::StateKey, QVariant> transactionStateBackup;
    QSet<ActionWrapper::StateKey> changedKeys; // 记录在事务中更改过的状态键

    // HandlerId 生成器
    HandlerId nextHandlerId;

public:
    // 开始事务
    void beginTransaction() {
        QMutexLocker locker(&mutex);
        if (inTransaction) {
            qWarning() << "事务已在进行中";
            return;
        }
        inTransaction = true;
        transactionStateBackup = state;
        changedKeys.clear();
    }

    // 提交事务
    void commitTransaction() {
        QMutexLocker locker(&mutex);
        if (!inTransaction) {
            qWarning() << "没有正在进行的事务";
            return;
        }
        inTransaction = false;

        // 发出所有更改过的状态键的信号
        for (const auto &key : changedKeys) {
            emit stateChanged(key, state[key]);
        }
        changedKeys.clear();

        transactionStateBackup.clear();
    }

    // 回滚事务
    void rollbackTransaction() {
        QMutexLocker locker(&mutex);
        if (!inTransaction) {
            qWarning() << "没有正在进行的事务";
            return;
        }
        state = transactionStateBackup;
        transactionStateBackup.clear();
        inTransaction = false;

        // 发出所有更改过的状态键的信号，通知状态已恢复
        for (const auto &key : changedKeys) {
            emit stateChanged(key, state[key]);
        }
        changedKeys.clear();
    }
};

#endif // HUBEN_HPP
